<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Leaflet</title>
    <link rel="stylesheet" href="leaflet.css" />
    <script src="leaflet.js"></script>
    <script src="plugins/leaflet-ant-path.js"></script>
    <!---->
    <script src="plugins/leaflet.rotatedMarker.js"></script>
    <!--计算点位方向-->
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
        height: 100%;
      }

      #map {
        height: 100vh;
      }
    </style>
  </head>

  <body>
    <div id="map"></div>

    <script>
      // 计算点位方向
      function calculateBearing(lat1, lon1, lat2, lon2) {
        const dLon = (lon2 - lon1) * (Math.PI / 180);
        const y = Math.sin(dLon) * Math.cos(lat2 * (Math.PI / 180));
        const x =
          Math.cos(lat1 * (Math.PI / 180)) * Math.sin(lat2 * (Math.PI / 180)) -
          Math.sin(lat1 * (Math.PI / 180)) *
            Math.cos(lat2 * (Math.PI / 180)) *
            Math.cos(dLon);
        let bearing = Math.atan2(y, x) * (180 / Math.PI);

        // 将方位角规范化为0到360度之间
        if (bearing < 0) {
          bearing = (bearing + 360) % 360;
        }

        return bearing;
      }

      const map = L.map("map").setView([28.23, 112.93], 13);

      L.tileLayer(
        "http://wprd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7",
        {
          minZoom: 11,
          maxZoom: 16
          // attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }
      ).addTo(map);

      const points = [
        [28.222, 112.92],
        [28.224, 112.922],
        [28.226, 112.924],
        [28.228, 112.926],
        [28.23, 112.928],
        [28.23, 112.93],
        [28.2321, 112.932],
        [28.234, 112.9342],
        [28.2361, 112.9361],
        [28.238, 112.938],
        [28.24, 112.94],
        [28.242, 112.942],
        [28.244, 112.944],
        [28.246, 112.946],
        [28.248, 112.948],
        [28.25, 112.95],
        [28.252, 112.952],
        [28.255, 112.955]
      ];

      const polylineStyleConfig = [
        {
          color: "#006600",
          fillColor: "#006600",
          pulseColor: "#e5ffe5"
        },
        {
          color: "#0000cc",
          fillColor: "#0000cc",
          pulseColor: "#ccccff"
        },
        {
          color: "#e62f00",
          fillColor: "#e62f00",
          pulseColor: "#ffc2b3"
        },
        {
          color: "#8600b3",
          fillColor: "#8600b3",
          pulseColor: "#ecb3ff"
        },
        {
          color: "#b35900",
          fillColor: "#b35900",
          pulseColor: "#ffd9b3"
        },
        {
          color: "#ff9900",
          fillColor: "#ff9900",
          pulseColor: "#ffe0b3"
        },
        {
          color: "#00b2b3",
          fillColor: "#00b2b3",
          pulseColor: "#b3ffff"
        },
        {
          color: "#000000",
          fillColor: "#000000",
          pulseColor: "#FFFFFF"
        },
        {
          color: "#006699",
          fillColor: "#006699",
          pulseColor: "#b3e6ff"
        },
        {
          color: "#cc0099",
          fillColor: "#cc0099",
          pulseColor: "#ffb3ec"
        }
      ];

      const iconConfig = [
        "./icon/car0.svg",
        "./icon/car1.svg",
        "./icon/car2.svg",
        "./icon/car3.svg",
        "./icon/car4.svg",
        "./icon/car5.svg",
        "./icon/car6.svg",
        "./icon/car7.svg",
        "./icon/car8.svg",
        "./icon/car9.svg"
      ];

      const layerGroups = {};

      // width：半径，单位为公里
      function drawPolyline(
        points,
        width,
        polylineStyleConfig,
        iconConfig,
        layerGroupName
      ) {
        if (points.length === 0) {
          return;
        }

        if (layerGroups[layerGroupName]) {
          map.removeLayer(layerGroups[layerGroupName]);
          layerGroups[layerGroupName] = L.layerGroup().addTo(map);
        } else {
          layerGroups[layerGroupName] = L.layerGroup().addTo(map);
        }

        // 起始点
        const marker = L.marker(points[0], {
          icon: L.icon({
            iconUrl: "./icon/nav.svg", // 图标图片的URL
            iconSize: [32, 32], // 图标的大小
            iconAnchor: [15, 15], // 图标的锚点，即图标的位置应该放置在地图上的位置
            popupAnchor: [-3, -76] // 弹出框的锚点，即当你点击图标时，弹出框应该出现在哪个位置
          })
        }).addTo(layerGroups[layerGroupName]);

        // 线
        L.polyline
          .antPath(points, {
            // 点的集合
            ...polylineStyleConfig,
            opacity: 6,
            delay: 10000,
            dashArray: [5, 30]
          })
          .addTo(layerGroups[layerGroupName]);

        // 最新的点
        L.marker(points[points.length - 1], {
          icon: L.icon({
            iconUrl: iconConfig,
            iconSize: [30, 30], // icon的大小
            iconAnchor: [16, 15], // icon的渲染的位置（相对与marker）
            shadowAnchor: [0, 0], // shadow的渲染的位置（相对于marker）
            popupAnchor: [0, 0] //若是绑定了popup的popup的打开位置（相对于icon）
          }),
          title: "test",
          draggable: true,
          rotationAngle:
            points.length > 1
              ? calculateBearing(
                  points[points.length - 2][0],
                  points[points.length - 2][1],
                  points[points.length - 1][0],
                  points[points.length - 1][1]
                )
              : 0
        }).addTo(layerGroups[layerGroupName]);

        const circle = L.circle(points[points.length - 1], {
          stroke: true,
          dashArray: "4",
          color: "red",
          fillColor: "#f03",
          fillOpacity: 0.2,
          weight: 2,
          radius: 1200 * width
        }).addTo(layerGroups[layerGroupName]);

        circle.on("mouseover", e => {
          alert("半径为0.5km.");
        });
      }

      let width = 0.25;

      const points2 = [];
      setInterval(function () {
        points.push([28.23 + Math.random() / 20, 112.93 + Math.random() / 20]);
        drawPolyline(points, width, polylineStyleConfig[0], iconConfig[0], "line1");
      }, 2000);
    </script>
  </body>
</html>
